import { Component, OnInit, EventEmitter } from "@angular/core";
import { Router, ActivatedRoute, Params } from '@angular/router';
import { Observable } from "rxjs/Observable";
import { Subscription } from "rxjs/Subscription";
import { SocketService } from "socket";

import { TreemapService } from "./treemap.service";
import { CLICKTYPE, SUBTYPE } from "../../lib/treemap/util";

@Component({
  templateUrl: "./quote-treemap.component.html",
  styleUrls: ["./quote-treemap.component.less"],
  providers: [ SocketService ]
})
export class QuoteTreemapComponent implements OnInit {
  tabList = [
    {
      text: "概念地图",
      url: "/GN"
    },
    {
      text: "行业地图",
      url: "/HY"
    },
    {
      text: "地域地图",
      url: "/DY"
    }
  ];
  mapDict = {
    GN: "所有概念",
    HY: "所有行业",
    DY: "所有地域"
  }
  config: Observable<any>;
  blockToggle: boolean = true;
  subLists: string[] = [];
  socketSubscription: Subscription;

  clickRectEmitter: Observable<any> = new EventEmitter();
  constructor (
    private route: ActivatedRoute,
    private router: Router,
    private socket: SocketService,
    private treemapService: TreemapService
  ) { }

  ngOnInit() {
    console.log('ngOnInit')
    let routerParamsStream = this.route.params
      .map(params => params["id"])
      .filter(id => !!id)
      .map(id => {
        this.blockToggle = true
        return { type: id }
      })
    let treemapSource = this.treemapService.getTreeMap()
      .do(data => console.log("%c 热力地图数据：", "color: #f00", data))
      .map(data => {
        let stockDict = new Map();
        data.forEach(d => {
          if (!stockDict.has(d.symbol)) {
            stockDict.set(d.symbol, d)
          }
        })
        return stockDict
      })

    let conbineStream = Observable.combineLatest(routerParamsStream, treemapSource, (block, stockDict) => {
      return {
        blockType: block.type,
        stockDict
      }
    })
    .do(data => console.log("%c 热力地图数据：", "color: #f00", data))
    
    this.config = conbineStream
      .switchMap(combineData => {
        return this.treemapService.getBlock(combineData.blockType)
          .map(data => ({
            combineData,
            config: {
              name: this.mapDict[combineData.blockType],
              children: data.filter(d => d.current > 0).map(d => ({
                ...d,
                value: Math.log2(+d.current)
              }))
            }
          }))
      })
      .do(data => console.log("%c 合并后的数据：", "color: #f00", data))
      .merge(this.clickRectEmitter)
      .filter(data => {
        if (data.type === CLICKTYPE && !(/XBHS/g).test(data.stockInfos.symbol)) {
          this.routeToggle(data.stockInfos.symbol)
          return false
        } else if (data.type === SUBTYPE) {
          return false
        } else {
          return true
        }
      })
      .switchMap(data => {
        if (data.type === CLICKTYPE) {
          console.log('%c 点击事件发生 ===>>> ', 'color: #f00', data)
          return this.treemapService.getBlock2symbols(data.stockInfos.symbol)
            .map(d => {
              return {
                clicked: true,
                symbol: data.stockInfos.symbol,
                symbols: d.symbols
              }
            })
        } else {
          return Observable.of(data)
        }
      })
      .do(data => console.log("%c switchMap 后的数据", "color: #0f0", data))
      .scan((accu, curr) => {
        if (curr.clicked) {
          console.log("%c 处理累加器数据：", "color: #0f0", accu, curr)
          let index = -1
          for (let i = 0; i < accu.config.children.length; i++) {
            if (accu.config.children[i].symbol === curr.symbol) {
              index = i;
              break;
            }
          }
          if (index > -1) {
            accu.config.children[index].children = curr.symbols.map(symbol => {
              return accu.combineData.stockDict.has(symbol)
                ? {
                  ...accu.combineData.stockDict.get(symbol),
                  value: Math.pow(+accu.combineData.stockDict.get(symbol).circulation_value, 0.1)
                }
                : null
            }).filter(d => d && d.value > 0)
          }
          return accu
        } else {
          if (this.blockToggle) {
            this.blockToggle = false;
            return curr
          } else {
            return accu
          }
        }
      }, {})
      .map(data => {
        return {
          data: data.config,
          clickRectEmitter: this.clickRectEmitter
        }
      })
      .do(data => console.log("%c 概念板块数据", "color: #f00", data))

    // // 订阅股票信息
    let subscirbeStockInfos = this.clickRectEmitter
    .filter(data => {
      return data.type === SUBTYPE ? true : false;
    })
    .scan((accu, curr) => {
      // if (accu.length > 0) {
      //   this.unsubStock([...accu])
      // }
      console.log('%c 需要退订的股票 ===>>>>> ', 'color: #0f0', accu)
      accu = [...curr.subLists]
      return accu
    }, [])

    this.socketSubscription = subscirbeStockInfos.subscribe(data => {
      console.log('%c 当前订阅的股票 ===>>>>> ', 'color: #0f0', data)
      this.subLists = [...data]
      // this.subStock(data)
    })

    this.socket.on('watchlist', data => {
      console.log('%c 查看我订阅板块 ===>>> ', 'color: #f00', data)
    })
  }

  ngOnDestroy() {
    console.log('%c 销毁组件退订股票 ===>>>>> ', 'color: #f0f', this.subLists)
    this.unsubStock(this.subLists)
    // 取消订阅
    this.socketSubscription ? this.socketSubscription.unsubscribe() : null;
  }

  // 订阅股票信息
  subStock(subLists) {
    this.socket.emit('sub', { channel: 'watchlist', symbols: [...subLists] })
  }

  // 取消股票订阅
  unsubStock(subLists) {
    if (subLists.length <= 0) return
    this.socket.emit('unsub', { channel: 'watchlist', symbols: [...subLists] })
  }

  // 路由跳转
  routeToggle(symbol) {
    this.router.navigate(['/stock', symbol.replace('.', '_')])
  }
}